<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>图片对比</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD"
          crossorigin="anonymous">
    <style>
        body {
            position: relative;
            padding-top: 100px;
            background-color: #f2f2f2;
        }

        form {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            background-color: white;
        }

        iframe {
            width: 800px;
            height: 800px;
        }
        #masking {
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            z-index: 10000;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 18px;
            color: white;
            background-color: rgba(0,0,0, .4);
            display: none;
        }
    </style>
</head>
<body v-scope="Test()">
<form class="p-3 pb-0">
    <div class="d-inline-block align-middle mb-3">
        <label for="iamge1">图片1</label>
        <input type="file" class="form-control d-inline-block w-auto" id="iamge1" @change="getFile($event,1)" accept="image/jpeg,application/pdf">
    </div>
    <div class="d-inline-block align-middle mb-3">
        <label for="iamge2">图片2</label>
        <input type="file" class="form-control d-inline-block w-auto" id="iamge2" @change="getFile($event,2)" accept="image/jpeg,application/pdf">
    </div>
    <div v-if="file1Type=='image'" class="d-inline-block align-middle mb-3">
        <label for="threshold">阈值</label>
        <input type="number" class="form-control d-inline-block w-auto" id="threshold" v-model="threshold">
    </div>
    <div class="d-inline-block align-middle mb-3">
        <button class="btn btn-primary" @click.stop="compare">对比</button>
    </div>
</form>
<div class="px-2">
    <div class="mb-4 text-center">
        <img v-if="file1Type=='image'" :src="file1LocalUrl" alt="">
        <iframe v-if="file1Type=='pdf'" :src="file1LocalUrl" frameborder="0"></iframe>
    </div>
    <div class="mb-4 text-center">
        <img v-if="file2Type=='image'" :src="file2LocalUrl" alt="">
        <iframe v-if="file2Type=='pdf'" :src="file2LocalUrl" frameborder="0"></iframe>
    </div>
    <div class="mb-4 text-center" @click="linkTagetBlank">
        <img v-if="compareResType=='image'" :src="compareResRemoteUrl" alt="">
        <iframe v-if="compareResType=='pdf'" :src="compareResRemoteUrl" frameborder="0"></iframe>
    </div>
</div>
<div v-if="comparing" id="masking" :style="{display: comparing ? 'flex' : 'none'}">
    数据对比中, 请耐心等待!
</div>
<script type="module">
    import {createApp} from 'https://unpkg.com/petite-vue?module'

    var acceptTypes = ['jpg', 'jpeg', 'png', 'pdf']
    var acceptImageTypes = ['jpg', 'jpeg', 'png']

    function readFile(file) {
        return new Promise((resolve, reject) => {
            let fr = new FileReader(),
                img = new Image();
            fr.onload = (frLoadEvent) => {

                img.onload = (imgLoadEvent) => {
                    resolve({
                        img: img,
                        url: frLoadEvent.target.result
                    })

                    img = null;
                };
                img.onerror = (imgErrorEvent) => {
                    reject({
                        valid: false,
                        message: '图片加载失败'
                    })
                };
                img.src = frLoadEvent.target.result

                img = null;
            };
            fr.onerror = (frErrorEvent) => {
                reject({
                    valid: false,
                    message: 'FileReader 读取文件失败'
                })
            };
            fr.readAsDataURL(file);
        })
    }

    function _upload(url, body) {
        return fetch(url, {
            method: 'POST',
            body: body
        }).then(res => res.json())
        .then(res=>{
            if(res.code == 1){
                return res;
            }else {
                return Promise.reject(res);
            }
        })
    }

    function uploadImage(threshold, file1, file2) {
        var body = new FormData()
        var url = `/compare/image2?threshold=${threshold}`
        body.append('files', file1)
        body.append('files', file2)
        return _upload(url, body)
    }

    function uploadPdf(pdf1File, pdf2File) {
        var body = new FormData()
        var url = `/compare/pdf`
        body.append('files', pdf1File)
        body.append('files', pdf2File)
        return _upload(url, body)
    }

    function upload(threshold, file1, file2) {
        if (!file1) {
            alert('请选择第一份需要对比的文件!')
            return Promise.reject()
        }
        if (!file2) {
            alert('请选择第二份需要对比的文件!')
            return Promise.reject()
        }
        var file1Type = validateFileTyle(file1)
        var file2Type = validateFileTyle(file2)
        if (!file1Type || !file2Type) {
            alert('仅支持jpg格式图片和pdf文件')
            return Promise.reject()
        }
        if (file1Type != file2Type) {
            alert('请提供相同类型的文件')
            return Promise.reject()
        }
        if (acceptImageTypes.includes(file1Type)) {
            return uploadImage(threshold, file1, file2)
        } else if(file1Type == 'pdf') {
            return uploadPdf(file1, file2)
        }
    }

    function validateFileTyle(file) {
        if(!file) return file;
        var type = file.type.split('/').pop()
        return acceptTypes.find(at => at == type)
    }

    function getType(fileType) {
        if (fileType == 'pdf') {
            return 'pdf'
        } else if (acceptImageTypes.includes(fileType)) {
            return 'image'
        } else {
            return ''
        }
    }

    function Test(props) {
        return {
            comparing: false,
            file1Type: 'image',
            file2Type: 'image',
            compareResType: 'image',
            threshold: 30,
            file1LocalUrl: '',
            file2LocalUrl: '',
            compareResRemoteUrl: '',
            file1: null,
            file2: null,
            compare(event) {
                this.comparing = true;
                event.preventDefault()
                this.compareResRemoteUrl = '';
                upload(this.threshold, this.file1, this.file2).then(res => {
                    console.log(res);
                    var data = res.data;
                    var type = data.fileName.split('.').pop()
                    this.compareResRemoteUrl = `${data.fileName}?t=${new Date().getMilliseconds()}`
                    this.compareResType = getType(acceptTypes.find(at => at == type))
                }).catch(err=>{
                    console.error(err)
                    alert(err.msg || err.error)
                }).finally(r=>{
                    this.comparing = false;
                })
            },
            getFile(event, type) {
                var file = event.target.files[0],
                    fileType = getType(validateFileTyle(file));
                this[`file${type}`] = file
                this[`file${type}Type`] = fileType
                if (fileType == 'image') {
                    readFile(file).then(res => {
                        this[`file${type}LocalUrl`] = res.url
                    })
                } else if (fileType == 'pdf') {
                    this[`file${type}LocalUrl`] = window.URL.createObjectURL(file)
                }
            },
            linkTagetBlank() {
                this.compareResRemoteUrl && window.open(this.compareResRemoteUrl, 'blank')
            }
        }
    }

    createApp({
        Test
    }).mount()
</script>
</body>
</html>
